﻿using IdentityModel;
using IdentityServer4.Stores;
using Newtonsoft.Json;
using System.Threading.Tasks;
using SqlSugar;
using D.IdentityDbStore.DbContext;
using D.IdentityDbStore.Entities;

namespace D.IdentityDbStore.Stores
{
    /// <summary>
    /// 设备流存储的实现。
    /// </summary>
    public class DeviceFlowStore : IDeviceFlowStore
    {

        private readonly ISqlSugarClient _db;

        public DeviceFlowStore(DbSql dbSql)
        {
            _db = dbSql.Db;
        }

        /// <summary>
        /// 根据设备代码查找设备授权
        /// </summary>
        /// <param name="deviceCode">设备代码</param>
        /// <returns></returns>
        public async Task<IdentityServer4.Models.DeviceCode> FindByDeviceCodeAsync(string deviceCode)
        {
            var model = await _db.Queryable<DeviceFlowCodes>().Where(m => m.DeviceCode == deviceCode).FirstAsync();
            return ToModel(model?.Data);
        }

        /// <summary>
        /// 按用户代码查找设备授权
        /// </summary>
        /// <param name="userCode">用户代码</param>
        /// <returns></returns>
        public async Task<IdentityServer4.Models.DeviceCode> FindByUserCodeAsync(string userCode)
        {
            var model = await _db.Queryable<DeviceFlowCodes>().Where(m => m.UserCode == userCode).FirstAsync();

            return ToModel(model?.Data);
        }

        /// <summary>
        /// 删除设备授权根据设备代码
        /// </summary>
        /// <param name="deviceCode">设备代码</param>
        /// <returns></returns>
        public async Task RemoveByDeviceCodeAsync(string deviceCode)
        {
            await _db.Deleteable<DeviceFlowCodes>().Where(m => m.DeviceCode == deviceCode).ExecuteCommandAsync();
        }

        /// <summary>
        /// 存储设备授权请求。
        /// </summary>
        /// <param name="deviceCode">设备代码</param>
        /// <param name="userCode">用户代码</param>
        /// <param name="data">数据</param>
        /// <returns></returns>
        public async Task StoreDeviceAuthorizationAsync(string deviceCode, string userCode, IdentityServer4.Models.DeviceCode data)
        {
            var model = ToEntity(data, deviceCode, userCode);
            await _db.Insertable<DeviceFlowCodes>(model).ExecuteCommandAsync();
        }

        /// <summary>
        /// 新设备授权，按用户代码搜索。
        /// </summary>
        /// <param name="userCode">用户代码</param>
        /// <param name="data">设备信息</param>
        /// <returns></returns>
        public async Task UpdateByUserCodeAsync(string userCode, IdentityServer4.Models.DeviceCode data)
        {
            var existing = await _db.Queryable<DeviceFlowCodes>().Where(m => m.UserCode == userCode).FirstAsync();
            if (existing != null)
            {
                var entity = ToEntity(data, existing.DeviceCode, userCode);

                existing.SubjectId = data.Subject?.FindFirst(JwtClaimTypes.Subject).Value;
                existing.Data = entity.Data;

                await _db.Updateable<DeviceFlowCodes>(existing).ExecuteCommandAsync();
            }
        }

        #region 实体转换

        protected DeviceFlowCodes ToEntity(IdentityServer4.Models.DeviceCode model, string deviceCode, string userCode)
        {
            if (model == null || deviceCode == null || userCode == null) return null;

            return new DeviceFlowCodes
            {
                DeviceCode = deviceCode,
                UserCode = userCode,
                ClientId = model.ClientId,
                SubjectId = model.Subject?.FindFirst(JwtClaimTypes.Subject).Value,
                CreationTime = model.CreationTime,
                Expiration = model.CreationTime.AddSeconds(model.Lifetime),
                Data = JsonConvert.SerializeObject(model)
            };
        }
        protected IdentityServer4.Models.DeviceCode ToModel(string entity)
        {
            if (entity == null) return null;

            return JsonConvert.DeserializeObject<IdentityServer4.Models.DeviceCode>(entity);
        }

        #endregion
    }
}
